package speedchina.controller.user;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import speedchina.controller.BaseController;
import speedchina.dto.PageParamDTO;
import speedchina.entity.user.Role;
import speedchina.enums.ResultEnum;
import speedchina.exception.BaseException;
import speedchina.service.user.RoleResourceService;
import speedchina.service.user.RoleService;
import speedchina.util.security.ShiroUtils;
import speedchina.vo.LayuiTableVO;
import speedchina.vo.ResultVO;

import javax.validation.Valid;
import java.util.Date;
import java.util.List;


/**
 * 角色信息
 *
 * @author 占超群
 */
@Controller
@RequestMapping("/system/role")
public class RoleController extends BaseController
{


    @Autowired
    private RoleService roleService;

    @Autowired
    private RoleResourceService roleResourceService;

    /**
     * 角色管理
     *
     * @return 角色管理页
     */
    @RequiresPermissions("system:role:view")
    @GetMapping("/view")
    public String role()
    {
        return "role/role";
    }



    /**
     * 新增保存角色
     *
     * @param role 角色信息
     * @return 统一结果
     */
    @RequiresPermissions("system:role:add")
    @PostMapping("/add")
    @Transactional(rollbackFor = Exception.class)
    @ResponseBody
    public ResultVO addSave(@Valid Role role)
    {
        role.setUpdateTime(new Date());
        List<Role> roleList = roleService.list(
            new QueryWrapper<Role>().eq("role_name", role.getRoleName())
                .or().eq("role_key", role.getRoleKey()));
        if (!roleList.isEmpty())
        {
            throw new BaseException(ResultEnum.ROLE_KEY_OR_NAME_ALREALY_HAVE);
        }
        return ResultVO.success(roleService.insertRole(role));
    }



    /**
     * 修改保存数据权限
     *
     * @param role 角色信息
     * @return 统一结果
     */
    @RequiresPermissions("system:role:edit")
    @PostMapping("/rule")
    @Transactional(rollbackFor = Exception.class)
    @ResponseBody
    public ResultVO ruleSave(Role role)
    {
        roleService.updateRule(role);
        return ResultVO.success();
    }

    /**
     * 批量根据id删除角色
     *
     * @param ids id的字符串
     * @return 统一结果
     */
    @RequiresPermissions("system:role:remove")
    @PostMapping("/remove")
    @ResponseBody
    public ResultVO remove(String ids)
    {
        try
        {
            return ResultVO.success(roleService.deleteRoleByIds(ids));
        }
        catch (Exception e)
        {
            return ResultVO.error(1, "不能删除");
        }
    }

    /**
     * 校验角色名称
     *
     * @param role 角色信息
     * @return 0或1 标识是否重复
     */
    @PostMapping("/checkRoleNameUnique")
    @ResponseBody
    public String checkRoleNameUnique(Role role)
    {
        return roleService.checkRoleNameUnique(role);
    }

    /**
     * 校验角色权限
     *
     * @param role 角色信息
     * @return 0或1 标识是否重复
     */
    @PostMapping("/checkRoleKeyUnique")
    @ResponseBody
    public String checkRoleKeyUnique(Role role)
    {
        return roleService.checkRoleKeyUnique(role);
    }


    /**
     * 分页获取项目
     *
     * @param pageParamDTO 分页参数
     * @param roleName     角色名
     * @return 角色layui table
     */
    @RequiresPermissions("system:role:list")
    @GetMapping("/list")
    @ResponseBody
    public LayuiTableVO list(PageParamDTO pageParamDTO, String roleName)
    {
        IPage<Role> page = new Page<>(pageParamDTO.getPage(), pageParamDTO.getSize());
        page = roleService.page(page,
            new QueryWrapper<Role>()
                .orderByDesc("update_time")
                .like(StringUtils.isNotBlank(roleName),"role_name", roleName));
        return getTableInfo(page);

    }

    /**
     * 删除指定id的角色
     *
     * @param roleId 角色id
     * @return 统一结果
     */
    @RequiresPermissions("system:role:remove")
    @DeleteMapping("/del/{roleId}")
    @ResponseBody
    public ResultVO del(@PathVariable("roleId") Long roleId)
    {
        return ResultVO.success(roleService.deleteRoleById(roleId));
    }

    /**
     * 修改角色
     *
     * @param roleId  角色id
     * @param role    角色信息
     * @param menuIds 菜单id字符串
     * @return
     */
    @RequiresPermissions("system:role:edit")
    @PutMapping("/update/{roleId}")
    @ResponseBody
    public ResultVO update(@PathVariable("roleId") Long roleId, Role role, Long[] menuIds)
    {
        role.setUpdateTime(new Date());
        role.setId(roleId);
        //操作角色和资源关系
        //1.先删除该角色的资源关联
        roleResourceService.deleteRoleMenuByRoleId(roleId);
        //2.再插入最新的资源组
        if (menuIds.length != 0)
        {
            roleResourceService.batchRoleResource(roleId, menuIds);
        }
        ShiroUtils.clearCachedAuthorizationInfo();
        return ResultVO.success(roleService.updateById(role));
    }

    /**
     * 跳转更新页面
     *
     * @param roleId 角色id
     * @param model  模型
     * @return 角色更新页面
     */
    @GetMapping("/update/{roleId}")
    public String updatePage(@PathVariable("roleId") Long roleId, Model model)
    {
        Role role = roleService.getById(roleId);

        model.addAttribute("role", role);
        return "role/update";
    }

    /**
     * 根据id获取当前项目信息
     *
     * @param roleId 角色id
     * @return 统一结果
     */
    @GetMapping("/{roleId}")
    @ResponseBody
    public ResultVO getById(@PathVariable("roleId") Long roleId)
    {
        return ResultVO.success(roleService.getById(roleId));
    }
}